package org.jeecg.modules.demo.com.kunpeng.client;

import lombok.SneakyThrows;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.*;
import java.net.URLDecoder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@RestController
public class DownloadClient {

    private final static long PER_PAGE=1024l * 1024l *50l;
    private final static String DOWN_PATH="F:\\fileItem";
    ExecutorService pool= Executors.newFixedThreadPool(10);


    //文件大小     文件名字
    //探测 获取文件信息
    //多线程分片下载
    //最后一个分片下载完  文件合并
    @RequestMapping("/downloadFile")
    public String downloadFile() throws Exception {
        FileInfo fileInfo = download(0, 10, -1, null);
        if(fileInfo!=null){
            long pages=fileInfo.fSize/PER_PAGE;
            for(long i=0;i<=pages;i++){
                pool.submit(new DownLoad(i * PER_PAGE,(i+1) * PER_PAGE-1,i,fileInfo.fName));
            }
        }
        return "success";
    }

    class DownLoad implements Runnable{

        long start;
        long end;
        long page;
        String fName;

        public DownLoad(long start, long end, long page, String fName) {
            this.start = start;
            this.end = end;
            this.page = page;
            this.fName = fName;
        }

        @SneakyThrows
        @Override
        public void run() {
            download(start, end, page, fName);
        }
    }

    class FileInfo{
        long fSize;
        String fName;

        public FileInfo(long fSize, String fName) {
            this.fSize = fSize;
            this.fName = fName;
        }
    }
    //结束的位置 -开始的位置  =  分片大小
    //临时存储分片文件
    private FileInfo download(long start,long end,long page,String fName) throws Exception{
        File file=new File(DOWN_PATH,page+"-"+fName);
        if(file.exists() && page != -1 && file.length() == PER_PAGE){
            return null;
        }
        HttpClient client= HttpClients.createDefault();
        HttpGet httpGet=new HttpGet("http://192.168.3.100:8080/jeecg-boot/com.kunpeng/supplierManagement/download");
        httpGet.setHeader("Range","bytes="+start+"-"+end);

            HttpResponse response = client.execute(httpGet);
            String fSize = response.getFirstHeader("fSize").getValue();
            fName= URLDecoder.decode(response.getFirstHeader("fName").getValue(),"utf-8");

            HttpEntity entity = response.getEntity();
            InputStream is = entity.getContent();

            FileOutputStream fos=new FileOutputStream(file);
            byte[] buffer=new byte[1024];
            int ch;
            while ((ch = is.read(buffer)) !=-1){
                fos.write(buffer,0,ch);
            }
            is.close();
            fos.flush();
            fos.close();
            if(end-Long.valueOf(fSize)>0){
                mergeFile(fName,page);
            }
            return new FileInfo(Long.valueOf(fSize),fName);
    }

    private void mergeFile(String fName, long page) throws Exception {
        File file=new File(DOWN_PATH,fName);
        BufferedOutputStream os=new BufferedOutputStream(new FileOutputStream(file));

        for(int i=0;i<=page;i++){
            File temFile=new File(DOWN_PATH,i+"-"+fName);

            while(!file.exists() || (i != page && file.length() < PER_PAGE)){
                Thread.sleep(100);
            }
            byte[] bytes = FileUtils.readFileToByteArray(temFile);
            os.write(bytes);
            os.flush();
            temFile.delete();
        }
        File file1=new File(DOWN_PATH,-1+"-null");
        file1.delete();
        os.flush();
        os.close();
    }
}
